/*
* memory usage debugging (from Asterisk)
*/
#ifndef __MEM_H__
#define __MEM_H__

#ifdef __cplusplus
extern "C" {
#endif

#ifndef va_copy
#define va_copy(dst, src)   memcpy(&(dst), &(src), sizeof(va_list))
#endif

#if defined (__GNUC__)
#  define __FUNC__     ((const char*) (__FUNC__))
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L
#  define __FUNC__     ((const char*) (__func__))
#else
#  define __FUNC__     ((const char*) (__FUNCTION__))
#endif

    /* Undefine any macros */
#undef malloc
#undef calloc
#undef free
#undef realloc
#undef strdup
#undef strndup
#undef asprintf
#undef vasprintf
    void *__mem_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
    void *__mem_malloc(size_t size, const char *file, int lineno, const char *func); 
    void __mem_free(void *ptr, const char *file, int lineno, const char *func);
    void *__mem_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func);
    char *__mem_strdup(const char *s, const char *file, int lineno, const char *func); 
    char *__mem_strndup(const char *s, size_t n, const char *file, int lineno,const char *func);
    int __mem_asprintf(const char *file, int lineno, const char *func, char **strp, const char *format, ...);
    int __mem_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func);

    /* Provide our own definitions */
#define calloc(a,b) \
    __mem_calloc(a,b,__FILE__, __LINE__, __FUNC__)
#define malloc(a) \
    __mem_malloc(a,__FILE__, __LINE__, __FUNC__)
#define free(a) \
    __mem_free(a,__FILE__, __LINE__, __FUNC__)
#define realloc(a,b) \
    __mem_realloc(a,b,__FILE__, __LINE__, __FUNC__)
#define strdup(a) \
    __mem_strdup(a,__FILE__, __LINE__, __FUNC__)
#define strndup(a,b) \
    __mem_strndup(a,b,__FILE__, __LINE__, __FUNC__)
#define asprintf(a, b, c,...) \
    __mem_asprintf(__FILE__, __LINE__, __FUNC__, a, b, c)
#define vasprintf(a,b,c) \
    __mem_vasprintf(a,b,c,__FILE__, __LINE__, __FUNC__)

    int show_memory(void);
    int show_memory_summary(void);

#ifdef __cplusplus
}
#endif

#endif /* __MEM_H__ */